home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / bench / ds3100.md / printStats.c < prev   
Encoding:
C/C++ Source or Header  |  1989-08-01  |  24.4 KB  |  711 lines

  1. /*
  2.  * printStats.c --
  3.  *    Routines to print out program execution times, and filesystem stats.
  4.  */
  5.  
  6. #include "sprite.h"
  7. #include "status.h"
  8. #include "sys/ioctl.h"
  9. #include "sys/file.h"
  10. #include "stdio.h"
  11. #include "proc.h"
  12. #include "vm.h"
  13. #include "sysStats.h"
  14. #include "kernel/fs.h"
  15. #include "kernel/fsStat.h"
  16. #include "kernel/sched.h"
  17. #include "kernel/vm.h"
  18.  
  19.  
  20.  
  21. /*
  22.  *----------------------------------------------------------------------
  23.  *
  24.  * PrintTimes --
  25.  *
  26.  *    Print the resource usage (user and kernel CPU time) and elapsed time.
  27.  *
  28.  * Results:
  29.  *    None.
  30.  *
  31.  * Side effects:
  32.  *    Prints to the specified stream
  33.  *
  34.  *----------------------------------------------------------------------
  35.  */
  36. void
  37. PrintTimes(stream, usagePtr, timePtr)
  38.     FILE *stream;
  39.     Proc_ResUsage *usagePtr;
  40.     Time *timePtr;
  41. {
  42.     Time delta;
  43.     if (usagePtr != NULL) {
  44.     Time_Add(usagePtr->userCpuUsage, usagePtr->childUserCpuUsage,
  45.                      &delta);
  46.     fprintf(stream, "%d.%03du ", delta.seconds,
  47.                    delta.microseconds / 1000);
  48.     Time_Add(usagePtr->kernelCpuUsage, usagePtr->childKernelCpuUsage,
  49.                      &delta);
  50.     fprintf(stream, "%d.%03ds ", delta.seconds,
  51.                    delta.microseconds / 1000);
  52.     }
  53.     if (timePtr != NULL) {
  54.     int seconds = timePtr->seconds;
  55.     if (seconds >= 3600) {
  56.         fprintf(stream, "%d:", seconds / 3600);
  57.         seconds = seconds % 3600;
  58.     }
  59.     if (seconds >= 60) {
  60.         fprintf(stream, "%d:", seconds / 60);
  61.         seconds = seconds % 60;
  62.     }
  63.     fprintf(stream, "%d.%03d", seconds,
  64.                    timePtr->microseconds / 1000);
  65.     }
  66.     fprintf(stream, "\n");
  67. }
  68.  
  69.  
  70. /*
  71.  *----------------------------------------------------------------------
  72.  *
  73.  * PrintIdleTime --
  74.  *
  75.  *    Given two samples sched module statistics, this computes
  76.  *    the differenc in idle ticks and, using the time, computes
  77.  *    a utilization.
  78.  *
  79.  * Results:
  80.  *    None.
  81.  *
  82.  * Side effects:
  83.  *    Prints to the specified stream
  84.  *
  85.  *----------------------------------------------------------------------
  86.  */
  87. void
  88. PrintIdleTime(stream, startSchedPtr, endSchedPtr, timePtr)
  89.     FILE *stream;
  90.     Sched_Instrument *startSchedPtr, *endSchedPtr;
  91.     Time *timePtr;
  92. {
  93.     register     highTicks;
  94.     double     lowTicks;
  95.     int        cpu;
  96.  
  97.     Sched_Instrument zeroStats;
  98.     if (startSchedPtr == NULL) {
  99.     bzero(&zeroStats, sizeof(Sched_Instrument));
  100.     startSchedPtr = &zeroStats;
  101.     }
  102.  
  103.     for (cpu=0; cpu<MACH_MAX_NUM_PROCESSORS; cpu++) {
  104.         highTicks = endSchedPtr->processor[cpu].idleTicksOverflow -
  105.         startSchedPtr->processor[cpu].idleTicksOverflow;
  106.         lowTicks = endSchedPtr->processor[cpu].idleTicksLow 
  107.         - startSchedPtr->processor[cpu].idleTicksLow;
  108.  
  109.         if (highTicks != 0) {
  110.         fprintf(stream, "(High ticks = %d)", highTicks);
  111.         }
  112.         if (timePtr->seconds == 0 && timePtr->microseconds == 0) {
  113.         fprintf(stream, "Idle ticks --/-- = 100%% Idle, Elapsed time ");
  114.         } else {
  115.         lowTicks /= 
  116.           (double)timePtr->seconds 
  117.             + (double) (timePtr->microseconds)/1000000.;
  118.         fprintf(stream, "Idle ticks %0.0f/%d = %6.2f%% Idle, Context Sw. %d inv %d full %d, Elapsed time ",
  119.                    lowTicks,
  120.             endSchedPtr->processor[cpu].idleTicksPerSecond,
  121.             (double)lowTicks/(double)endSchedPtr->processor[cpu].idleTicksPerSecond * 100.,
  122.             endSchedPtr->processor[cpu].numContextSwitches 
  123.                 - startSchedPtr->processor[cpu].numContextSwitches,
  124.                    endSchedPtr->processor[cpu].numInvoluntarySwitches 
  125.                 - startSchedPtr->processor[cpu].numInvoluntarySwitches,
  126.                    endSchedPtr->processor[cpu].numFullCS 
  127.                 - startSchedPtr->processor[cpu].numFullCS);
  128.         }
  129.         PrintTimes(stream, (Proc_ResUsage *)0, timePtr);
  130.     }
  131. }
  132.  
  133.  
  134. /*
  135.  *----------------------------------------------------------------------
  136.  *
  137.  * PrintFsStats --
  138.  *
  139.  *    Print out the filesystem statistics.  If both a start and end
  140.  *    sample of the statistics are given then the differences between
  141.  *    the two are printed.  To just print the total cumulative statistics
  142.  *    from one sample, specify a single FsStats buffer with the 'end'
  143.  *    parameter.
  144.  *
  145.  * Results:
  146.  *    None.
  147.  *
  148.  * Side effects:
  149.  *    Prints to the specified stream
  150.  *
  151.  *----------------------------------------------------------------------
  152.  */
  153. void
  154. PrintFsStats(stream, start, end, verbose)
  155.     FILE *stream;    /* Output stream */
  156.     FsStats *start;    /* 0, or address of "before run" statistics */
  157.     FsStats *end;    /* End of run statistics */
  158.     int verbose;    /* If true, everything is dumped */
  159. {
  160.     register int t1, t2, t3, t4, t5;
  161.     FsStats zeroStats;
  162.  
  163.     if (start == (FsStats *)0) {
  164.     bzero(&zeroStats, sizeof(FsStats));
  165.     start = &zeroStats;
  166.     }
  167.     /*
  168.      * Print cache size
  169.      */
  170.     fprintf(stream, "Cache blocks max %d min %d number %d/%d free %d/%d limit %d\n",
  171.                end->blockCache.maxCacheBlocks,
  172.                end->blockCache.minCacheBlocks,
  173.                start->blockCache.numCacheBlocks,
  174.                end->blockCache.numCacheBlocks,
  175.                start->blockCache.numFreeBlocks,
  176.                end->blockCache.numFreeBlocks,
  177.                end->blockCache.maxNumBlocks);
  178.  
  179.     /*
  180.      * Print bytes read traffic ratio
  181.      */
  182.     t1 = end->blockCache.bytesRead - start->blockCache.bytesRead;
  183.     t2 = end->blockCache.dirBytesRead - start->blockCache.dirBytesRead;
  184.     t3 = end->gen.remoteBytesRead - start->gen.remoteBytesRead;
  185.     t4 = end->gen.fileBytesRead - start->gen.fileBytesRead;
  186.     t5 = end->gen.physBytesRead - start->gen.physBytesRead;
  187.     fprintf(stream, "Bytes read %d+%d remote %d disk %d+%d",
  188.                t1, t2, t3, t4, t5);
  189.     if (t1 + t2 > 0) {
  190. #ifdef stupid_compiler
  191.     fprintf(stream, "\ttraffic ratio %%%d\n",
  192.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  193. #else
  194.     fprintf(stream, "\n");
  195. #endif
  196.     } else {
  197.     fprintf(stream, "\n");
  198.     }
  199.  
  200.     /*
  201.      * Print bytes written traffic ratio
  202.      */
  203.     t1 = end->blockCache.bytesWritten - start->blockCache.bytesWritten +
  204.     (end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  205.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites) *
  206.     FS_BLOCK_SIZE;
  207.     t2 = end->blockCache.dirBytesWritten - start->blockCache.dirBytesWritten;
  208.     t3 = end->gen.remoteBytesWritten - start->gen.remoteBytesWritten;
  209.     t4 = end->gen.fileBytesWritten - start->gen.fileBytesWritten;
  210.     t5 = end->gen.physBytesWritten - start->gen.physBytesWritten;
  211.     fprintf(stream, "Bytes written %d+%d remote %d disk %d+%d",
  212.                t1, t2, t3, t4, t5);
  213. #ifdef stupid_compiler
  214.     if (t1 + t2 > 0) {
  215.     fprintf(stream, "\ttraffic ratio %%%d",
  216.                (int)((double)(t3+t4+t5)/(double)(t1+t2) * 100.));
  217.     }
  218. #endif
  219.     fprintf(stream, "\n");
  220.  
  221.     if (verbose) {
  222.     /*
  223.      * Print device bytes and zero fills
  224.      */
  225.     t1 = end->gen.deviceBytesWritten - start->gen.deviceBytesWritten;
  226.     t2 = end->gen.deviceBytesRead - start->gen.deviceBytesRead;
  227.     fprintf(stream, "Dev bytes read %d written %d\n", t1, t2);
  228.     t1 = end->blockCache.readZeroFills - start->blockCache.readZeroFills;
  229.     t2 = end->blockCache.writeZeroFills1 -
  230.         start->blockCache.writeZeroFills1;
  231.     t3 = end->blockCache.writeZeroFills2 -
  232.         start->blockCache.writeZeroFills2;
  233.     t4 = end->blockCache.fragZeroFills - start->blockCache.fragZeroFills;
  234.     fprintf(stream, "Zero Fills read %d write1 %d write2 %d frag %d\n",
  235.                    t1, t2, t3, t4);
  236.     t1 = end->blockCache.appendWrites - start->blockCache.appendWrites;
  237.     t2 = end->blockCache.overWrites - start->blockCache.overWrites;
  238.     t3 = end->blockCache.domainReadFails -
  239.         start->blockCache.domainReadFails;
  240.     fprintf(stream, "Appends %d Overwrites %d Failed Reads %d\n",
  241.                    t1, t2, t3);
  242.     }
  243.     t1 = end->blockCache.readAccesses - start->blockCache.readAccesses +
  244.      end->blockCache.fragAccesses - start->blockCache.fragAccesses +
  245.      end->blockCache.fileDescReads - start->blockCache.fileDescReads +
  246.      end->blockCache.indBlockAccesses - start->blockCache.indBlockAccesses +
  247.      end->blockCache.dirBlockAccesses - start->blockCache.dirBlockAccesses;
  248.     t2 = end->blockCache.readHitsOnDirtyBlock -
  249.     start->blockCache.readHitsOnDirtyBlock;
  250.     t3 = end->blockCache.readHitsOnCleanBlock -
  251.     start->blockCache.readHitsOnCleanBlock;
  252.     t4 = end->blockCache.fragHits - start->blockCache.fragHits +
  253.      end->blockCache.fileDescReadHits - start->blockCache.fileDescReadHits +
  254.      end->blockCache.indBlockHits - start->blockCache.indBlockHits +
  255.      end->blockCache.dirBlockHits - start->blockCache.dirBlockHits;
  256.     fprintf(stream, "Cache reads %d hits: dirty %d clean %d other %d",
  257.                t1, t2, t3, t4);
  258. #ifdef stupid_compiler
  259.     if (t1 != 0) {
  260.     fprintf(stream, "\thit ratio %%%d",
  261.                (int)((double)(t2+t3+t4)/(double)t1 * 100.));
  262.     }
  263. #endif
  264.     fprintf(stream, "\n");
  265.  
  266.     t1 = end->blockCache.readAheads - start->blockCache.readAheads;
  267.     t2 = end->blockCache.readAheadHits - start->blockCache.readAheadHits;
  268.     t3 = end->blockCache.allInCacheCalls - start->blockCache.allInCacheCalls;
  269.     t4 = end->blockCache.allInCacheTrue - start->blockCache.allInCacheTrue;
  270.     if (t1 > 0) {
  271.     fprintf(stream, "Read Ahead: hits %d/%d all-in-cache %d/%d\n",
  272.             t2, t1, t4, t3);
  273.     }
  274.  
  275.     t1 = end->blockCache.writeAccesses - start->blockCache.writeAccesses +
  276.      end->blockCache.fileDescWrites - start->blockCache.fileDescWrites +
  277.      end->blockCache.indBlockWrites - start->blockCache.indBlockWrites +
  278.      end->blockCache.dirBlockWrites - start->blockCache.dirBlockWrites;
  279.     t2 = end->blockCache.partialWriteHits - start->blockCache.partialWriteHits +
  280.     end->blockCache.fileDescWriteHits - start->blockCache.fileDescWriteHits;
  281.     t3 = end->blockCache.partialWriteMisses -
  282.     start->blockCache.partialWriteMisses;
  283.     t4 = end->blockCache.blocksWrittenThru -
  284.     start->blockCache.blocksWrittenThru;
  285.     fprintf(stream, "Cache writes %d hits %d misses %d thru %d",
  286.                t1, t2, t3, t4);
  287. #ifdef stupid_compiler
  288.     if (t1 != 0) {
  289.     fprintf(stream, "\ttraffic ratio %%%d",
  290.                (int)((double)(t3+t4)/(double)t1 * 100.));
  291.     }
  292. #endif
  293.     fprintf(stream, "\n");
  294.     
  295.     fprintf(stream, "Write thru %d data %d indirect %d desc %d dir %d\n",
  296.                t4,
  297.                end->blockCache.dataBlocksWrittenThru -
  298.                start->blockCache.dataBlocksWrittenThru,
  299.                end->blockCache.indBlocksWrittenThru -
  300.                start->blockCache.indBlocksWrittenThru,
  301.                end->blockCache.descBlocksWrittenThru -
  302.                start->blockCache.descBlocksWrittenThru,
  303.                end->blockCache.dirBlocksWrittenThru -
  304.                start->blockCache.dirBlocksWrittenThru);
  305.     if (end->blockCache.fileDescReads > 0) {
  306.     fprintf(stream, "File descriptor reads %d hits %d writes %d hits %d\n",
  307.                    end->blockCache.fileDescReads -
  308.                    start->blockCache.fileDescReads,
  309.                    end->blockCache.fileDescReadHits -
  310.                    start->blockCache.fileDescReadHits,
  311.                    end->blockCache.fileDescWrites -
  312.                    start->blockCache.fileDescWrites,
  313.                    end->blockCache.fileDescWriteHits -
  314.                    start->blockCache.fileDescWriteHits);
  315.     }
  316.     if (end->blockCache.indBlockAccesses > 0) {
  317.     fprintf(stream, "Indirect block reads %d hits %d writes %d\n",
  318.                end->blockCache.indBlockAccesses -
  319.                start->blockCache.indBlockAccesses,
  320.                end->blockCache.indBlockHits -
  321.                start->blockCache.indBlockHits,
  322.                end->blockCache.indBlockWrites -
  323.                start->blockCache.indBlockWrites);
  324.     }
  325.     if (end->blockCache.dirBlockAccesses > 0) {
  326.     fprintf(stream, "Directory block reads %d hits %d writes %d\n",
  327.                    end->blockCache.dirBlockAccesses -
  328.                    start->blockCache.dirBlockAccesses,
  329.                    end->blockCache.dirBlockHits -
  330.                    start->blockCache.dirBlockHits,
  331.                    end->blockCache.dirBlockWrites -
  332.                    start->blockCache.dirBlockWrites);
  333.     }
  334.     if (end->blockCache.vmRequests > 0) {
  335.     fprintf(stream, "VM requests %d tried %d gave %d\n",
  336.                    end->blockCache.vmRequests -
  337.                    start->blockCache.vmRequests,
  338.                    end->blockCache.triedToGiveToVM -
  339.                    start->blockCache.triedToGiveToVM,
  340.                    end->blockCache.vmGotPage -
  341.                    start->blockCache.vmGotPage);
  342.     }
  343.     fprintf(stream, "Cache blocks created %d, alloc from free %d part %d lru %d\n",
  344.                    end->blockCache.unmapped -
  345.                    start->blockCache.unmapped,
  346.                    end->blockCache.totFree -
  347.                    start->blockCache.totFree,
  348.                    end->blockCache.partFree -
  349.                    start->blockCache.partFree,
  350.                    end->blockCache.lru -
  351.                    start->blockCache.lru);
  352.     if (end->alloc.blocksAllocated > 0) {
  353.     fprintf(stream, "Disk blocks alloc %d free %d search %d/%d hash %d\n",
  354.                    end->alloc.blocksAllocated -
  355.                    start->alloc.blocksAllocated,
  356.                    end->alloc.blocksFreed -
  357.                    start->alloc.blocksFreed,
  358.                    end->alloc.cylsSearched -
  359.                    start->alloc.cylsSearched,
  360.                    end->alloc.cylBitmapSearches -
  361.                    start->alloc.cylBitmapSearches,
  362.                    end->alloc.cylHashes -
  363.                    start->alloc.cylHashes);
  364.     fprintf(stream, "Fragments alloc %d free %d upgrade %d blocks made %d used %d, bad hints %d\n",
  365.                    end->alloc.fragsAllocated -
  366.                    start->alloc.fragsAllocated,
  367.                    end->alloc.fragsFreed -
  368.                    start->alloc.fragsFreed,
  369.                    end->alloc.fragUpgrades -
  370.                    start->alloc.fragUpgrades,
  371.                    end->alloc.fragToBlock -
  372.                    start->alloc.fragToBlock,
  373.                    end->alloc.fullBlockFrags -
  374.                    start->alloc.fullBlockFrags,
  375.                    end->alloc.badFragList -
  376.                    start->alloc.badFragList);
  377.     }
  378.     if (end->nameCache.accesses > 0) {
  379.     fprintf(stream, "Name cache entries %d accesses %d hits %d replaced %d\n",
  380.                end->nameCache.size,
  381.                end->nameCache.accesses -
  382.                start->nameCache.accesses,
  383.                end->nameCache.hits -
  384.                start->nameCache.hits,
  385.                end->nameCache.replacements -
  386.                start->nameCache.replacements);
  387.     }
  388.     fprintf(stream, "Handles %d created %d installed %d hits %d old %d version %d flush %d\n",
  389.                end->handle.exists,
  390.                end->handle.created -
  391.                start->handle.created,
  392.                end->handle.installCalls -
  393.                start->handle.installCalls,
  394.                end->handle.installHits -
  395.                start->handle.installHits,
  396.                0,
  397.                end->handle.versionMismatch -
  398.                start->handle.versionMismatch,
  399.                end->handle.cacheFlushes -
  400.                start->handle.cacheFlushes);
  401.     fprintf(stream, "\tfetched %d hits %d released %d locks %d/%d wait %d\n",
  402.                end->handle.fetchCalls -
  403.                start->handle.fetchCalls,
  404.                end->handle.fetchHits -
  405.                start->handle.fetchHits,
  406.                end->handle.release -
  407.                start->handle.release,
  408.                end->handle.locks -
  409.                start->handle.locks,
  410.                end->handle.locks -
  411.                start->handle.locks,
  412.                end->handle.lockWaits -
  413.                start->handle.lockWaits);
  414.     fprintf(stream, "Segments fetched %d hits %d\n",
  415.                end->handle.segmentFetches -
  416.                start->handle.segmentFetches,
  417.                end->handle.segmentHits -
  418.                start->handle.segmentHits);
  419.     fprintf(stream, "Lookup relative %d absolute %d redirect %d found %d loops %d timeouts %d stale %d\n",
  420.                end->prefix.relative -
  421.                start->prefix.relative,
  422.                end->prefix.absolute -
  423.                start->prefix.absolute,
  424.                end->prefix.redirects -
  425.                start->prefix.redirects,
  426.                end->prefix.found -
  427.                start->prefix.found,
  428.                end->prefix.loops -
  429.                start->prefix.loops,
  430.                end->prefix.timeouts -
  431.                start->prefix.timeouts,
  432.                end->prefix.stale -
  433.                start->prefix.stale);
  434. }
  435.  
  436.  
  437. /*
  438.  *----------------------------------------------------------------------
  439.  *
  440.  * PrintDiskStats --
  441.  *
  442.  *    Print out statistics for the disks.  If both a start and end
  443.  *    sample of the statistics are given then the differences between
  444.  *    the two are printed.  To just print the total cumulative statistics
  445.  *    from one sample, specify a single VmStats buffer with the 'end'
  446.  *    parameter.
  447.  *
  448.  * Results:
  449.  *    None.
  450.  *
  451.  * Side effects:
  452.  *    Prints to the specified stream
  453.  *
  454.  *----------------------------------------------------------------------
  455.  */
  456. void
  457. PrintDiskStats(stream, start, end)
  458.     FILE        *stream;    /* Output stream */
  459.     Sys_DiskStats    *start;    /* 0, or address of "before run" statistics */
  460.     Sys_DiskStats    *end;    /* End of run statistics */
  461. {
  462.     int    i = 0;
  463.     while (1) {
  464.     if (end[i].name[0] == 0) {
  465.         return;
  466.     }
  467.     if (start == 0) {
  468.         fprintf(stream, "Disk (%s, %d): %0.2f%% Idle Reads %d Writes %d\n",
  469.             end[i].name, end[i].controllerID,
  470.             100 * ((float)end[i].idleCount / (float)end[i].numSamples),
  471.             end[i].diskReads, end[i].diskWrites);
  472.     } else {
  473.         fprintf(stream, "Disk (%s, %d) %0.0f%% Idle Reads %d Writes %d\n",
  474.             end[i].name, end[i].controllerID,
  475.             100 * ((float)(end[i].idleCount - start[i].idleCount) /
  476.                    (float)(end[i].numSamples - start[i].numSamples)),
  477.             end[i].diskReads - start[i].diskReads,
  478.             end[i].diskWrites - start[i].diskWrites);
  479.     }
  480.     i++;
  481.     }
  482. }
  483.  
  484.  
  485. /*
  486.  *----------------------------------------------------------------------
  487.  *
  488.  * PrintVmStats --
  489.  *
  490.  *    Print out VM statistics.  If both a start and end
  491.  *    sample of the statistics are given then the differences between
  492.  *    the two are printed.  To just print the total cumulative statistics
  493.  *    from one sample, specify a single VmStats buffer with the 'end'
  494.  *    parameter.
  495.  *
  496.  * Results:
  497.  *    None.
  498.  *
  499.  * Side effects:
  500.  *    Prints to the specified stream
  501.  *
  502.  *----------------------------------------------------------------------
  503.  */
  504. void
  505. PrintVmStats(stream, start, end)
  506.     FILE *stream;    /* Output stream */
  507.     Vm_Stat *start;    /* 0, or address of "before run" statistics */
  508.     Vm_Stat *end;    /* End of run statistics */
  509. {
  510.     register    int    *diffPtr;
  511.     register    int    *startPtr;
  512.     register    int    *endPtr;
  513.     int            i;
  514.     int            inusePages;
  515.     int            totPages;
  516.     int            numModifiedPages;
  517.     Vm_Stat        diffStat;
  518.     int            totPercent;
  519.     int            totFaults;
  520.     int            heapPercent;
  521.     int            stkPercent;
  522.     int            quickPercent;    
  523.     int            totHits;
  524.     int            totPrefetches;
  525.     int            hitPct;
  526.  
  527.     startPtr = (int *)start;
  528.     endPtr = (int *)end;
  529.     diffPtr = (int *)&diffStat;
  530.  
  531.     for (i = 0; 
  532.          i < sizeof(Vm_Stat) / sizeof(int); 
  533.      i++, startPtr++, endPtr++, diffPtr++) {
  534.     *diffPtr = *endPtr - *startPtr;
  535.     }
  536.  
  537.     (void)Vm_Cmd(VM_COUNT_DIRTY_PAGES, &numModifiedPages);
  538.     fprintf(stream, "Kernel VM Pages: %d (Code+Data=%d Stacks=%d)\n",
  539.          end->kernMemPages + end->kernStackPages,
  540.          end->kernMemPages, end->kernStackPages);
  541.     inusePages = end->numDirtyPages + end->numUserPages;
  542.     totPages = end->numFreePages + inusePages;
  543.     fprintf(stream, "User VM Pages:   %d (Free=%d Dirty=%d Res=%d Alloc-list=%d)\n",
  544.         end->numFreePages + end->numDirtyPages + 
  545.         end->numReservePages + end->numUserPages, 
  546.         end->numFreePages, end->numDirtyPages,
  547.         end->numReservePages,
  548.         end->numUserPages);
  549.     fprintf(stream, "Modified pages: Total=%d %%Tot-dirty=%0.2f %%Inuse-dirty=%0.2f\n",
  550.         numModifiedPages,
  551.         (float) (numModifiedPages) / (float)totPages * 100.0,
  552.         (float) (numModifiedPages) / (float)inusePages * 100.0);
  553.     fprintf(stream, "FS Pages: Current=%d Max=%d Min=%d\n", 
  554.         end->fsMap - end->fsUnmap, end->maxFSPages, end->minFSPages);
  555.     fprintf(stream,
  556.          "Faults: %8d (Zero=%d FS=%d Swap=%d Quick=%d Coll=%d)\n", 
  557.          diffStat.totalFaults, diffStat.zeroFilled, diffStat.fsFilled,
  558.          diffStat.psFilled,diffStat.quickFaults, diffStat.collFaults);
  559.     fprintf(stream, "        %8d (Code=%d Heap=%d Stack=%d)\n", 
  560.          diffStat.totalFaults, diffStat.codeFaults, diffStat.heapFaults,
  561.          diffStat.stackFaults);
  562.     fprintf(stream, 
  563.         "Mod page stats:  Pot-mod=%d Not-mod=%d Not-hard-mod=%d\n",
  564.         diffStat.potModPages, diffStat.notModPages, 
  565.         diffStat.notHardModPages);
  566.  
  567.     /*
  568.      * Copy on write. 
  569.      */
  570.     totPages = diffStat.numCOWStkPages + diffStat.numCOWHeapPages;
  571.     totFaults = diffStat.numCOWStkFaults + diffStat.numCOWHeapFaults;
  572.     if (diffStat.numCOWHeapPages > 0) {
  573.     heapPercent = 100.0 * ((float)diffStat.numCOWHeapFaults / 
  574.                       diffStat.numCOWHeapPages);
  575.     } else {
  576.     heapPercent = 0;
  577.     }
  578.     if (diffStat.numCOWStkPages > 0) {
  579.     stkPercent = 100.0 * ((float)diffStat.numCOWStkFaults / 
  580.                       diffStat.numCOWStkPages);
  581.     } else {
  582.     stkPercent = 0;
  583.     }
  584.     if (totPages > 0) {
  585.     totPercent = 100.0 * ((float)totFaults / totPages);
  586.     } else {
  587.     totPercent = 0;
  588.     }
  589.     if (totFaults > 0) {
  590.     quickPercent = 100.0 * ((float)diffStat.quickCOWFaults / totFaults);
  591.     } else {
  592.     quickPercent = 0;
  593.     }
  594.     fprintf(stream, 
  595.         "COW: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  596.         diffStat.numCOWHeapFaults, diffStat.numCOWHeapPages, heapPercent,
  597.         diffStat.numCOWStkFaults, diffStat.numCOWStkPages, stkPercent,
  598.         totFaults, totPages, totPercent);
  599.     fprintf(stream, "     Quick (%d/%d)=%d%%\n",
  600.         diffStat.quickCOWFaults, totFaults, quickPercent);
  601.     /*
  602.      * Copy on reference.
  603.      */
  604.     totPages = diffStat.numCORStkPages + diffStat.numCORHeapPages;
  605.     totFaults = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  606.     if (diffStat.numCORHeapPages > 0) {
  607.     heapPercent = 100.0 * ((float)diffStat.numCORHeapFaults / 
  608.                       diffStat.numCORHeapPages);
  609.     } else {
  610.     heapPercent = 0;
  611.     }
  612.     if (diffStat.numCORStkPages > 0) {
  613.     stkPercent = 100.0 * ((float)diffStat.numCORStkFaults / 
  614.                       diffStat.numCORStkPages);
  615.     } else {
  616.     stkPercent = 0;
  617.     }
  618.     if (totPages > 0) {
  619.     totPercent = 100.0 * ((float)totFaults / totPages);
  620.     } else {
  621.     totPercent = 0;
  622.     }
  623.     fprintf(stream,
  624.             "COR: Heap (%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  625.         diffStat.numCORHeapFaults, diffStat.numCORHeapPages, heapPercent,
  626.         diffStat.numCORStkFaults, diffStat.numCORStkPages, stkPercent,
  627.         totFaults, totPages, totPercent);
  628.     totPages = diffStat.numCORStkFaults + diffStat.numCORHeapFaults;
  629.     totFaults = diffStat.numCORCOWStkFaults + diffStat.numCORCOWHeapFaults;
  630.     if (diffStat.numCORCOWHeapFaults > 0) {
  631.     heapPercent = 100.0 * ((float)diffStat.numCORCOWHeapFaults / 
  632.                       diffStat.numCORHeapFaults);
  633.     } else {
  634.     heapPercent = 0;
  635.     }
  636.     if (diffStat.numCORCOWStkFaults > 0) {
  637.     stkPercent = 100.0 * ((float)diffStat.numCORCOWStkFaults / 
  638.                       diffStat.numCORStkFaults);
  639.     } else {
  640.     stkPercent = 0;
  641.     }
  642.     if (totPages > 0) {
  643.     totPercent = 100.0 * ((float)totFaults / totPages);
  644.     } else {
  645.     totPercent = 0;
  646.     }
  647.     fprintf(stream,
  648.             "COR-mod: Heap(%d/%d)=%d%% Stk (%d/%d)=%d%% Tot (%d/%d)=%d%%\n",
  649.         diffStat.numCORCOWHeapFaults, diffStat.numCORHeapFaults,heapPercent,
  650.         diffStat.numCORCOWStkFaults, diffStat.numCORStkFaults, stkPercent,
  651.         diffStat.numCORCOWHeapFaults + diffStat.numCORCOWStkFaults,
  652.         diffStat.numCORHeapFaults + diffStat.numCORStkFaults, totPercent);
  653.  
  654.     fprintf(stream, "Swap pages copied: %d\n", diffStat.swapPagesCopied);
  655.     fprintf(stream,
  656.              "Vm allocs: %d (Free=%d From-FS=%d From-alloc-list=%d)\n",
  657.          diffStat.numAllocs, diffStat.gotFreePage, diffStat.gotPageFromFS, 
  658.          diffStat.pageAllocs);
  659.     fprintf(stream, 
  660.          "VM-FS stats: Asked=%d Free-pages=%d Allocs=%d Frees=%d\n",
  661.          diffStat.fsAsked, diffStat.haveFreePage, diffStat.fsMap, 
  662.          diffStat.fsUnmap);
  663.     fprintf(stream, "Alloc-list searches: %d (Free=%d In-use=%d)\n",
  664.          diffStat.numListSearches, diffStat.usedFreePage, 
  665.          diffStat.numListSearches - diffStat.usedFreePage);
  666.     fprintf(stream, "Extra-searches: %d (Lock=%d Ref=%d Dirty=%d)\n",
  667.          diffStat.lockSearched + diffStat.refSearched + 
  668.          diffStat.dirtySearched,
  669.          diffStat.lockSearched, diffStat.refSearched, 
  670.          diffStat.dirtySearched);
  671.     fprintf(stream, "Pages written %d\n", diffStat.pagesWritten);
  672.  
  673.     totPrefetches = diffStat.codePrefetches + diffStat.heapFSPrefetches +
  674.             diffStat.heapSwapPrefetches + diffStat.stackPrefetches;
  675.     if (totPrefetches > 0) {
  676.     totHits = diffStat.codePrefetchHits + diffStat.heapFSPrefetchHits +
  677.           diffStat.heapSwapPrefetchHits + diffStat.stackPrefetchHits;
  678.     fprintf(stream, "Prefetch stats:\n");
  679.     if (diffStat.codePrefetches > 0) {
  680.         hitPct = 100 * ((float)diffStat.codePrefetchHits / 
  681.                 (float)diffStat.codePrefetches);
  682.         fprintf(stream, "    code (%d/%d)=%d%%\n",
  683.             diffStat.codePrefetchHits, diffStat.codePrefetches, hitPct);
  684.     }
  685.     if (diffStat.heapFSPrefetches > 0) {
  686.         hitPct = 100 * ((float)diffStat.heapFSPrefetchHits / 
  687.                 (float)diffStat.heapFSPrefetches);
  688.         fprintf(stream, "    heap-fs (%d/%d)=%d%%\n",
  689.         diffStat.heapFSPrefetchHits, diffStat.heapFSPrefetches, hitPct);
  690.     }
  691.     if (diffStat.heapSwapPrefetches > 0) {
  692.         hitPct = 100 * ((float)diffStat.heapSwapPrefetchHits / 
  693.                 (float)diffStat.heapSwapPrefetches);
  694.         fprintf(stream, "    heap-swp (%d/%d)=%d%%\n",
  695.         diffStat.heapSwapPrefetchHits, diffStat.heapSwapPrefetches, 
  696.         hitPct);
  697.     }
  698.     if (diffStat.stackPrefetches > 0) {
  699.         hitPct = 100 * ((float)diffStat.stackPrefetchHits / 
  700.                 (float)diffStat.stackPrefetches);
  701.         fprintf(stream, "    stack (%d/%d)=%d%%\n",
  702.         diffStat.stackPrefetchHits, diffStat.stackPrefetches, hitPct);
  703.     }
  704.     hitPct = 100 * ((float)totHits / (float)totPrefetches);
  705.     fprintf(stream, "    total (%d/%d)=%d%%\n",
  706.         totHits, totPrefetches, hitPct);
  707.     fprintf(stream, "    aborts=   %d\n", diffStat.prefetchAborts);
  708.     }
  709. }
  710.  
  711.